--
-- Author: shunguo.chen
-- Date: 2018-04-18 14:36:27
--
-- GuideRender  引导render
--

local Armature = app:getClass("Armature")

local ClassRef = app.mvc.createRenderClass(...)

local GAP = 10

--data =
function ClassRef.createWithData(data, node)
    local sprite = ClassRef.extend(node or cc.CSLoader:createNode(Res.GuideTipNode))
    if node == nil then
        ccui.Helper:doLayout(sprite)
    end
    sprite:init(data)
    return sprite
end
function ClassRef.create(node)
    return ClassRef.createWithData(nil, node)
end

-- data = Guide
function ClassRef:init(data)
    self.super.init(self, data)

    self._ui.Panel:setTouchEnabled(false)

    self._textSize = self._ui.Text:getContentSize()
    self._panelSize = self._ui.Panel:getContentSize()
    self._timeline = self:getTimeline()

    local lightEfc = cc.CSLoader:createNode(Res.GuideLightNode)
    self:addChild(lightEfc, -1)
    self._lightEfc = lightEfc

    self:refresh()
end

function ClassRef:show()
    self:setVisible(true)
    self._timeline:gotoFrameAndPlay(0, false)
    self._lightEfc:getTimeline():gotoFrameAndPlay(0, true)
end

function ClassRef:hide()
    self:setVisible(false)
    self._timeline:pause()
    self._lightEfc:getTimeline():pause()
end

function ClassRef:_isPointInRange(x, y)
    if self._data:isPointTrigger() then
        return cc.pGetDistance(self._data.triggerPos, cc.p(x, y)) <= self._data.triggerRadius
    else
        local isModal = self._data:isModal()
        if isModal then
            return cc.rectContainsPoint(self._rect, cc.p(x, y))
        else
            -- 非模态，需要实时算rect
            local worldPos = self:convertToWorldSpace(cc.p(0, 0))
            local rect = self._rect
            rect.x = worldPos.x - rect.width/2
            rect.y = worldPos.y - rect.height/2
            self._rect = rect
            return cc.rectContainsPoint(self._rect, cc.p(x, y))
        end
    end
end

function ClassRef:_touchClose()
    local layer = display.newNode()
    self:addChild(layer, 10)
    local isCanCancel = self._data:isCanCancel()
    local startInRange = false
    -- 支线任务引导，点击范围外取消引导
    self._touchListener = display.nodeTouchOneByOne(layer,
        function(x, y)
            startInRange = self:_isPointInRange(x, y)
            -- print("GuideRender TouchBegan in range", self._data.id, startInRange)
            if isCanCancel then
                return true
            else
                return startInRange
            end
        end,
        function(x, y)
            local endInRange = self:_isPointInRange(x, y)
            local isOver, isCancel = false, false
            if isCanCancel then
                if endInRange == startInRange then
                    isOver = true
                    isCancel = not endInRange
                end
            else
                isOver = endInRange
            end

            if isOver then
                -- print("GuideRender TouchEnded in range", self._data.id)
                -- 点击之后有时间，还需要延迟才关闭
                layer:removeFromParent()
                if isCancel then
                    self:_cancel()
                else
                    if self._data.closeTime then
                        self:hideHandArmature()

                        -- 如果parent是GuideView，nodeRetrurn
                        local parent = self:getParent()
                        if parent:getName() == "GuideView" then
                            parent:nodeReturn()
                        end

                        self:_delayClose(self._data.closeTime)
                    else
                        self:_close()
                    end
                end
            end

        end)
end

function ClassRef:_cancel()
    EM:notify("cancelGuide", self._data)
    executeFunc(self._onClick, self)
end

function ClassRef:_close()
    EM:notify("compGuide", self._data, self._params)
    executeFunc(self._onClick, self)
end

function ClassRef:_delayClose(time)
    self:performWithDelay(function()
            self:_close()
        end, time)
end

function ClassRef:refresh()
    if self._data then
        local guide = self._data

        local isShowTip = guide:isShowTip()
        self._ui.Panel:setVisible(isShowTip)
        if isShowTip then
            -- desc
            self._ui.Text:setTextAreaSize(cc.size(self._textSize.width, 0))
            self._ui.Text:setString(guide:getDesc())

            local size = self._ui.Text:getVirtualRendererSize()
            size.height = size.height + 4
            self._ui.Text:setTextAreaSize(size)
            local dis = size.height - self._textSize.height
            if dis > 0 then
                self._ui.Panel:setContentSize(cc.size(self._panelSize.width, self._panelSize.height + dis))
            else
                self._ui.Panel:setContentSize(self._panelSize)
            end
            ccui.Helper:doLayout(self._ui.Panel)

            -- tip pos
            local isUpTip = guide:isUpTip()
            local factor = isUpTip and 1 or -1
            local rotate = isUpTip and 0 or 180
            self._ui.Panel:setPositionY(guide.tipY * factor)
            self._ui.Panel:setRotation(rotate)
            self._ui.Text:setRotation(rotate)
            self._ui.Text:setPositionY(self._ui.Text:getPositionY() - factor * 2)

            if not guide.triggerNpcId then
                -- avoid out screen
                local worldPos = self:convertToWorldSpace(cc.p(0,0))
                local dis = 0
                if worldPos.x < (self._panelSize.width / 2 + GAP) then
                    dis = self._panelSize.width / 2 + GAP - worldPos.x
                elseif worldPos.x > (display.width - self._panelSize.width / 2 - GAP) then
                    dis = (display.width - self._panelSize.width / 2 - GAP) - worldPos.x
                end

                self._ui.Panel:setPositionX(dis)
                self._ui.arrow:setPositionX(self._panelSize.width / 2 - factor * dis)
            else
                -- npc 不需要处理
            end
        end

        -- ui zoom
        self._lightEfc:setScale(guide.effectZoom)

        -- close type
        if guide.closeType == 1 then
            -- 点击关闭
            self:playHandArmature()
            self:_touchClose()
        elseif guide.closeType == 2 then
            -- 时间到关闭
            self:_delayClose(guide.closeTime)
        end
    end
end

-- 播放手动画
function ClassRef:playHandArmature()
    local armature = self._handArmature
    local conf = Res.GuideFinger
    if not armature then
        local guide = self._data
        local params = {
            armatureName = conf.name,
            path = conf.dir
        }
        armature = Armature.create(params)
        armature:setPosition(guide.handX, guide.handY)
        armature:setScale(guide.handZoom)
        self:addChild(armature, 10)
        self._handArmature = armature
    end

    armature:setVisible(true)
    armature:play(conf.action)
end

function ClassRef:hideHandArmature()
    if self._handArmature then
        self._handArmature:stop()
        self._handArmature:setVisible(false)
    end
end

-- 引导开始信息
function ClassRef:setStartData(params)
    self._params = params
end
function ClassRef:getStartData()
    return self._params
end

-- 当前有效点击区域
function ClassRef:setSelectRect(rect)
    self._rect = rect
end

-- 结束回调
function ClassRef:onBtnClick(cb)
    self._onClick = cb
end

return ClassRef
